﻿/// <summary>
/// <Filename>: Motion_ToolsClass.cs
/// Author: Jiang Xiaolong
/// Created: 2015.01.26
/// Version: 1.0
/// Company: Sunnytech
/// Function: Motion运动平台工具类；
///
/// Changed By:
/// Modification Time:
/// Discription:
/// <summary>
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Reflection;
using System.Data;
using Motion.MotionPlatform.Tools;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace Motion.MotionPlatform
{
	/// <summary>
	/// 用于Motion类中相关参数记录；
	/// </summary>
	public class Motion_Data
	{
		/* *****************************
		 * 可能更改的常量，应该写到文件中
		 * *****************************/
		public static string GroupTable = "Group";  //Group表名
		public static string ID = "ID";  //ID列名称
		public static string platformExtension = "/Extension/PlatformExtension.xls";  //平台扩展配置文件路径
		public static string MainScriptStr = "MainScript";  //主脚本所在物体名称
		public static int TimeColIndex = 7;  //时间列列号
		public static int IDColIndex = 1;  //ID列列号

		/* *****************
		 * Motion平台全局变量
		 * ****************/
		public static bool IsAutoAssemble = false;  //是否自动生成装配表
		public static bool IsAutoTime = false;  //是否自动生成时间
		public static bool IsCreatePosition = false;  //是否生成位置信息
		public static int IDChartCount = 0;  //列表数量
		public static string taskRootPath = "";  //当前案例根目录
		public static int CurrentExcelIndex = 0;  //当前表格索引
		public static bool IsContinue = false;  //是否连续生成

		public static string CurrentBranch = "";  //当前分支
		public static bool IsVarProcess = false;  //是否在随机变量修改过程 By吴浩 06112015
		public static int VarProcessTable = 1;  //是否在随机变量修改过程 By吴浩 07142015
		public static int VarProcessRow = 2;  //是否在随机变量修改过程 By吴浩 07142015

		/* *******************************************
		 * Motion平台全局变量，原来在MotionPara中的参数
		 * *******************************************/
		public static bool PauseControl = false;  //运动暂停控制
		public static bool MotionActive = false;  //运动激活控制
		public static float SpeedRate = 1.0f;  //运动速率
		//是否为编辑器模式下，为true时，读取表格时格式错误会报错
		public static bool isEditor = false;

		/* ***************
		 * ALLSHEET表格参数
		 * ***************/
		//所有需要加载的Sheet名
		public static List<string> AllSheetName = new List<string>();
		//需要设置ID为主键的Sheet名；
		public static List<string> MainIDRow = new List<string>();

		/* ***********
		 * MAIN表格参数
		 * ***********/
		//Main表参与运动的列
		public static List<string> MainSheetCol = new List<string>();
		//Main表Collumn ID对应列号
		public static Dictionary<string, int> MainColIndex = new Dictionary<string, int>();
		//Main表当前列可以容纳的运动项及其教练考允许状态
		public static Dictionary<string, Dictionary<string, string>> MainColItem = new Dictionary<string, Dictionary<string, string>>();
		//Main Collumn在当前状态下是否运行
		public static Dictionary<string, string> MainItemAllow = new Dictionary<string, string>();
		//Main表Collumn ID对应列是否同步运行
		public static Dictionary<string, bool> MainIsSynchronized = new Dictionary<string, bool>();

		/* *******************
		 * Funciton功能表格参数
		 * ******************/
		//对应的功能类名
		public static List<string> FunctionList = new List<string>();
		//功能类对应解析类
		public static Dictionary<string, string> FucntionParseDic = new Dictionary<string, string>();
		//相关功能类的反射类名索引
		public static Dictionary<string, Dictionary<string, string>> MotionFunctionClassDic = new Dictionary<string, Dictionary<string, string>>();
		//相关功能类的运行允许条件索引
		public static Dictionary<string, Dictionary<string, string>> MotionFunctionAllowDic = new Dictionary<string, Dictionary<string, string>>();

	
		static Motion_Data()
		{
			Clear();
			//加载相关表格
			ExcelInit();
		}

		public static void Clear()
		{
			AllSheetName.Clear();
			MainIDRow.Clear();
			MainSheetCol.Clear();
			MainColIndex.Clear();
			MainColItem.Clear();
			MainItemAllow.Clear();
			MainIsSynchronized.Clear();
			FunctionList.Clear();
			FucntionParseDic.Clear();
			MotionFunctionClassDic.Clear();
			MotionFunctionAllowDic.Clear();

		}

		//表格初始化
		private static void ExcelInit()
		{
			ExcelOperator opReader = new ExcelOperator();
			string filePath = Application.streamingAssetsPath + platformExtension;

			//所有Sheet和ID为主键的Sheet
			DataTable allSheetTable = opReader.ExcelReader(filePath, "ALLSHEET", "A", "B");
			if (allSheetTable == null)
			{
				Debug.LogError("路径：" + filePath + "，Sheet：ALLSHEET，该运动平台配置表格加载为空，请检查！");
				return;
			}
			for (int i = 0; i < allSheetTable.Rows.Count; i++)
			{
				string sheetName = (string)allSheetTable.Rows[i][0].ToString();
				if (sheetName != "")
				{
					AllSheetName.Add(sheetName);
					string flagStr = (string)allSheetTable.Rows[i][1].ToString();
					if (flagStr.ToUpper() == "TRUE")
					{
						MainIDRow.Add(sheetName);
					}
				}
			}

			//Main表相关参数加载
			DataTable mainSheetTable = opReader.ExcelReader(filePath, "MAIN", "A", "E");
			if (mainSheetTable == null)
			{
				Debug.LogError("路径：" + filePath + "，Sheet：MAIN，该运动平台配置表格加载为空，请检查！");
				return;
			}
			for (int i = 0; i < mainSheetTable.Rows.Count; i++)
			{
				//Collumn Motion Name Parse
				string mainColName = ((string)mainSheetTable.Rows[i][0].ToString()).Trim();
				if (mainColName != "")
				{
					MainSheetCol.Add(mainColName);
					//Collumn Index Parse
					int colIndex = -1;
					try
					{
						colIndex = int.Parse((string)mainSheetTable.Rows[i][1].ToString());
					}
					catch
					{
						Debug.LogWarning("路径：" + filePath + "，Sheet：MAIN，位置：（" + (i + 2).ToString() + "，B），该空格内容转化为int出错，请检查！");
						continue;
					}
					MainColIndex.Add(mainColName, colIndex);
					//Collumn Motion Item Parse
					string allItemStr = ((string)mainSheetTable.Rows[i][2].ToString()).Trim();
					if (allItemStr != "")
					{
						MainColItem.Add(mainColName, new Dictionary<string, string>());
						string[] itemArray = allItemStr.Split('|');
						for (int j = 0; j < itemArray.Length; j++)
						{
							string[] specificItemArray = itemArray[j].Split('@');
							if (specificItemArray.Length == 2 && specificItemArray[1].Trim().Length == 3)
							{
								MainColItem[mainColName].Add(specificItemArray[0], specificItemArray[1].Trim());
								//加载所有的功能项，以便后面加载相应功能项对应的类名
								if (FunctionList.IndexOf(specificItemArray[0]) == -1)
								{
									FunctionList.Add(specificItemArray[0]);
								}
							}
							else
							{
								Debug.LogWarning("路径：" + filePath + "，Sheet：MAIN，位置：（" + (i + 2).ToString() + "，C），Content：" + itemArray[j] + "，该内容格式不正确，请检查！");
								continue;
							}
						}
					}
					else
					{
						Debug.LogWarning("路径：" + filePath + "，Sheet：MAIN，位置：（" + (i + 2).ToString() + "，C），该空格内容为空，请检查！");
						continue;
					}
					//Collumn Allow Judge
					string allowStr = ((string)mainSheetTable.Rows[i][3].ToString()).Trim();
					if (allowStr.Length == 3)
					{
						MainItemAllow.Add(mainColName, allowStr);
					}
					else
					{
						Debug.LogWarning("路径：" + filePath + "，Sheet：MAIN，位置：（" + (i + 2).ToString() + "，D），该空格长度应为3个字符，请检查！");
						continue;
					}
					//是否同步运行
					string isSynchronizd = ((string)mainSheetTable.Rows[i][4].ToString()).Trim();
					if (isSynchronizd.ToUpper() == "TRUE")
					{
						MainIsSynchronized.Add(mainColName, true);
					}
					else
					{
						MainIsSynchronized.Add(mainColName, false);
					}
				}
				else
				{
					Debug.LogWarning("路径：" + filePath + "，Sheet：MAIN，位置：（" + (i + 2).ToString() + "，A），该空格内容为空，请检查！");
				}
			}

			//相关Function表格加载
			for (int i = 0; i < FunctionList.Count; i++)
			{
				DataTable functionSheetTable = opReader.ExcelReader(filePath, FunctionList[i], "A", "C");
				if (mainSheetTable == null)
				{
					Debug.LogError("路径：" + filePath + "，Sheet：" + FunctionList[i] + "，该运动平台配置表格加载为空，请检查！");
					continue;
				}
				MotionFunctionClassDic.Add(FunctionList[i], new Dictionary<string, string>());
				MotionFunctionAllowDic.Add(FunctionList[i], new Dictionary<string, string>());
				for (int j = 0; j < functionSheetTable.Rows.Count; j++)
				{
					string motionTypeID = ((string)functionSheetTable.Rows[j][0].ToString()).Trim();
					if (motionTypeID != "")
					{
						string motionClassID = ((string)functionSheetTable.Rows[j][1].ToString()).Trim();
						if (motionClassID != "")
						{
							if (j == 0)  //第一行为解析类
							{
								//加载解析类
								FucntionParseDic.Add(FunctionList[i], motionClassID);
								continue;
							}
							string allowStr = ((string)functionSheetTable.Rows[j][2].ToString()).Trim();
							if (allowStr.Length == 3)
							{
								//加载数据
								MotionFunctionClassDic[FunctionList[i]].Add(motionTypeID.ToUpper(), motionClassID);
								MotionFunctionAllowDic[FunctionList[i]].Add(motionTypeID.ToUpper(), allowStr);
							}
							else
							{
								Debug.LogWarning("路径：" + filePath + "，Sheet：" + FunctionList[i] + "，位置：（" + (i + 2).ToString() + "，C），该空格长度应为3个字符，请检查！");
								continue;
							}
						}
						else
						{
							Debug.LogWarning("路径：" + filePath + "，Sheet：" + FunctionList[i] + "，位置：（" + (i + 2).ToString() + "，B），该空格内容为空，请检查！");
							continue;
						}
					}
					else
					{
						Debug.LogWarning("路径：" + filePath + "，Sheet：" + FunctionList[i] + "，位置：（" + (i + 2).ToString() + "，A），该空格内容为空，请检查！");
						continue;
					}
				}
			}

		}

		/// <summary>
		/// 当前列在教练考时是否运行；
		/// </summary>
		/// <param name="col_symbol">当前列标志符；</param>
		/// <param name="state">教练考状态，0：教，1：练，2：考；</param>
		/// <returns></returns>
		public static bool MainCollumnAllow(string col_symbol, int state)
		{
			if (MainItemAllow.ContainsKey(col_symbol))
			{
				if (MainItemAllow[col_symbol][state] == '0')
				{
					return false;
				}
				else
				{
					return true;
				}
			}
			else
			{
				return false;
			}
		}

		/// <summary>
		/// 当前列中的某一个Function在教练考时是否运行；
		/// </summary>
		/// <param name="col_symbol">当前列标志符；</param>
		/// <param name="function_symbol">当前列标志符；</param>
		/// <param name="state">教练考状态，0：教，1：练，2：考；</param>
		/// <returns></returns>
		public static bool MainCollumnFunctionAllow(string col_symbol, string function_symbol, int state)
		{
			if (MainColItem.ContainsKey(col_symbol) && MainColItem[col_symbol].ContainsKey(function_symbol))
			{
				if (MainColItem[col_symbol][function_symbol][state] == '0')
				{
					return false;
				}
				else
				{
					return true;
				}
			}
			else
			{
				return false;
			}
		}

		/// <summary>
		/// 某一个Function中的若干子功能在教练考时是否运行；
		/// </summary>
		/// <param name="function_symbol">当前功能ID；</param>
		/// <param name="sub_function_symbol">当前功能ID对应的子功能ID；</param>
		/// <param name="state">教练考状态，0：教，1：练，2：考；</param>
		/// <returns></returns>
		public static bool MotionFunctionAllow(string function_symbol, string sub_function_symbol, int state)
		{
			if (MotionFunctionAllowDic.ContainsKey(function_symbol) && MotionFunctionAllowDic[function_symbol].ContainsKey(sub_function_symbol))
			{
				if (MotionFunctionAllowDic[function_symbol][sub_function_symbol][state] == '0')
				{
					return false;
				}
				else
				{
					return true;
				}
			}
			else
			{
				return false;
			}
		}
	}

	
	/// <summary>
	/// 计算基类.
	/// </summary>
	public class Motion_Compute
	{
		//标点符号占用语音的时间记录
		private static Dictionary<char, float> punctutionDic = new Dictionary<char, float>();

		static Motion_Compute()
		{
			punctutionDic.Add(',', 0.4f); punctutionDic.Add('，', 0.4f);
			punctutionDic.Add('.', 1.5f); punctutionDic.Add('。', 1.5f);
			punctutionDic.Add('!', 1.5f); punctutionDic.Add('！', 1.5f);
			punctutionDic.Add('?', 1.5f); punctutionDic.Add('？', 1.5f);
			punctutionDic.Add(':', 0.5f); punctutionDic.Add('：', 0.5f);
			punctutionDic.Add(';', 0.5f); punctutionDic.Add('；', 0.5f);
			punctutionDic.Add('、', 0.15f); 
		}

		//字符串转化为Vector3
		public static Vector3 Vector3Conversion(string info, ref bool is_right)
		{
			Vector3 rVector3 = new Vector3(0, 0, 0);
			string[] infoArray = info.Split(',', '，');
			try
			{
				rVector3.x = (float)Convert.ToDouble(infoArray[0]);
				rVector3.y = (float)Convert.ToDouble(infoArray[1]);
				rVector3.z = (float)Convert.ToDouble(infoArray[2]);
			}
			catch
			{
				is_right = false;
			}
			return rVector3;
		}

		//字符串转化为Rect
		public static Rect RectConversion(string info, ref bool is_right)
		{
			Rect rRect = new Rect(0, 0, 0, 0);
			string[] infoArray = info.Split(',', '，');
			try
			{
				rRect.x = (float)Convert.ToDouble(infoArray[0]);
				rRect.y = (float)Convert.ToDouble(infoArray[1]);
				rRect.width = (float)Convert.ToDouble(infoArray[2]);
				rRect.height = (float)Convert.ToDouble(infoArray[3]);
			}
			catch
			{
				is_right = false;
			}
			return rRect;
		}

		//字符串转化为Vector2
		public static Vector2 Vector2Conversion(string info, ref bool is_right)
		{
			Vector2 rVector2 = new Vector3(0, 0);
			string[] infoArray = info.Split(',', '，');
			try
			{
				rVector2.x = (float)Convert.ToDouble(infoArray[0]);
				rVector2.y = (float)Convert.ToDouble(infoArray[1]);
			}
			catch
			{
				is_right = false;
			}
			return rVector2;
		}

		//字符串转化为float
		public static float FloatConversion(string info, ref bool is_right)
		{
			float rFloat = 0;
			try
			{
				rFloat = float.Parse(info);
			}
			catch
			{
				is_right = false;
			}
			return rFloat;
		}

		//字符串转化为int
		public static int IntConversion(string info, ref bool is_right)
		{
			int rInt = 0;
			try
			{
				rInt = int.Parse(info);
			}
			catch
			{
				is_right = false;
			}
			return rInt;
		}

		//字符串转化为int
		public static bool BoolConversion(string info, ref bool is_right)
		{
			bool bo = false;
			if (info.ToUpper() == "TRUE")
			{
				return true;
			}
			else if (info.ToUpper() == "FALSE")
			{
				return false;
			}
			else
			{
				is_right = false;
			}
			return bo;
		}

		//角度值统一转化，效果不好暂不用
		private static Vector3 AngleConversion(Vector3 ori_vec)
		{
			if (ori_vec.x < 0)
				ori_vec.x += 360f;
			if (ori_vec.y < 0)
				ori_vec.y += 360f;
			if (ori_vec.z < 0)
				ori_vec.z += 360f;
			return ori_vec;
		}

		//角度值统一转化，效果不好暂不用
		private static Vector3 AngleDiff(Vector3 ori_vec)
		{
			if (ori_vec.x < -180f)
				ori_vec.x += 360f;
			else if (ori_vec.x > 180f)
				ori_vec.x = 360f - ori_vec.x;
			if (ori_vec.y < -180f)
				ori_vec.y += 360f;
			else if (ori_vec.y > 180f)
				ori_vec.y = 360f - ori_vec.y;
			if (ori_vec.z < -180f)
				ori_vec.z += 360f;
			else if (ori_vec.z > 180f)
				ori_vec.z = 360f - ori_vec.z;
			return ori_vec;
		}

		//获取角度差值
		public static Vector3 GetAngleDiff(Vector3 start_angle, ref Vector3 end_angle)
		{
			end_angle.x = AngleClerp(start_angle.x, end_angle.x, 1f);
			end_angle.y = AngleClerp(start_angle.y, end_angle.y, 1f);
			end_angle.z = AngleClerp(start_angle.z, end_angle.z, 1f);
			return end_angle - start_angle;
		}

		//角度修改使其符合实际（类似-90和270这种情况处理）
		private static float AngleClerp(float start, float end, float value)
		{
			float min = 0.0f;
			float max = 360.0f;
			float half = Mathf.Abs((max - min) / 2.0f);
			float retval = 0.0f;
			float diff = 0.0f;
			if ((end - start) < -half)
			{
				diff = ((max - start) + end) * value;
				retval = start + diff;
			}
			else if ((end - start) > half)
			{
				diff = -((max - end) + start) * value;
				retval = start + diff;
			}
			else retval = start + (end - start) * value;
			return retval;
		}

		/// <summary>
		/// 获得语音播放时长；
		/// </summary>
		/// <param name="tips_str">所读的字符串；</param>
		/// <returns>语音速率为1.0时的播放时长；</returns>
		public static float GetPlayTime(string tips_str)
		{
			float rTime = 0;
			//标点符号占用时间
			float punctuationTime = 0;
			//字符数量
			int charNum = 0;
			char[] tipsCharArray = tips_str.ToCharArray();
			for (int i = 0; i < tipsCharArray.Length; i++)
			{
				if (punctutionDic.ContainsKey(tipsCharArray[i]))
				{
					if (i != tipsCharArray.Length - 1)
					{
						punctuationTime += punctutionDic[tipsCharArray[i]];
					}
				}
				else
				{
					charNum++;
				}
			}
			if (charNum <= 4)
				rTime = 3f + punctuationTime;
			else
				rTime = 3f + punctuationTime + (charNum - 4) * 0.2f;
			//Debug.LogError("字符数：" + charNum + "; 标点符号占用时间: " + punctuationTime + "; 字符占用时间：" + (rTime - punctuationTime).ToString());
			return rTime;
		}

		//将Excel中参数转换成参数表里面的数据
		public static void ExcelDataAnalysis(ref DataRow data_row, string motion_symbol, DataTable group_table)
		{
			List<string> data_row_Content = new List<string>();
			for (int i = 0; i < data_row.Table.Columns.Count; i++)
			{
				try
				{
					data_row_Content.Add(data_row[i].ToString().Trim());
				}
				catch {
					break;
				}
			}

			if (!Motion_Data.IsVarProcess && Motion_Data.isEditor)
			{
				
				bool isRight = true;

				string tmpExcel = Motion.MotionPlatform.MotionPlatformData.excelName;
				int tmpRow = (Motion.MotionPlatform.MotionPlatformData.mainRowNumber + 2);

				//检查影响到的物体
				if (motion_symbol == "EXCEL")
				{
					string tmpExcelContent = "EXCEL@" + data_row_Content[1];

					//该行运动的物体组
					List<string> groupObjs = new List<string>();
					//Group Column
					int groupColumn = Motion.MotionPlatform.Motion_Compute.IntConversion(data_row_Content[2], ref isRight) + 1;
					//运动物体信息
					string objName = "";
					objName = (string)group_table.Rows[0][groupColumn].ToString();
					if (!groupObjs.Contains(objName))
					{
						GameObject tmpObj = GameObject.Find(objName);
						if (tmpObj == null)
						{
							Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "文件中Group" + data_row_Content[2] + "物体组中" + objName + "物体在场景中不存在");
						}

						VariableManager.TransformRecursion(tmpObj.transform, groupObjs);	
						//TODO_ERROR:GameObject.Find检查
					}
					for (int j = 1; j < group_table.Rows.Count; j++)
					{
						objName = (string)group_table.Rows[j][groupColumn].ToString();
						if (objName == "")
							break;
						if (!groupObjs.Contains(objName))
						{
							GameObject tmpObj = GameObject.Find(objName);
							if (tmpObj == null)
							{
								Debug.LogError(Motion.MotionPlatform.MotionPlatformData.excelName + "文件中Group" + data_row_Content[2] + "物体组中" + objName + "物体在场景中不存在");
							}
							VariableManager.TransformRecursion(tmpObj.transform, groupObjs);
							//TODO_ERROR:GameObject.Find检查
						}
					}
					//相对物体
					string referenceObj = "";
					if (data_row_Content[11] != "")
					{
						referenceObj = data_row_Content[11];
					}

					//被影响的Excel
					string tmpRelatedExcel = tmpExcel + "_" + tmpRow + "_" + tmpExcelContent;

					//检查当前表格是否被随机变量或输入变量影响
					List<string> tmpList = new List<string>();

					bool hasVariable = false;
					for (int i = 1; i < data_row_Content.Count; i++)
					{
						if (data_row[i].ToString() != "")
						{
							string[] tmpStr2 = data_row[i].ToString().Split(',');
							for (int j = 0; j < tmpStr2.Length; j++)
							{
								string tmpVar = tmpStr2[j].Substring(1);
								if (tmpVar.Contains("$"))
								{
									string[] tmpStrsss = tmpVar.Split('$');
									tmpVar = tmpStrsss[0];
								}
								//Debug.Log("tmpVar:" + tmpVar);
								if (tmpStr2[j][0] == '$' && Expression.impl.ExpressionManager.IsCreatedExpression(tmpVar) && Expression.impl.ExpressionManager.GetExpression(tmpVar).ToString().Contains("RANDOM"))
								{
									hasVariable = true;
								}
							}
						}
					}

					if (!hasVariable)
					{
						//for (int i = 0; i < CheckVar._SpecialVars.Count; i++)
						for (int i = CheckVar._SpecialVars.Count - 1; i >= 0; i--)
						{
							if (!tmpList.Contains(CheckVar._SpecialVars[i].VarID))
							{
								tmpList.Add(CheckVar._SpecialVars[i].VarID);
							}
							else {
								continue;
							}

							//判断物体组是否被随机变量，输入变量影响。
							for (int j = 0; j < CheckVar._SpecialVars[i].relatedObj.Count; j++)
							{
								//运动物体组中包含 随机变量的影响物体:在随机变量中添加影响行
								if (groupObjs.Contains(CheckVar._SpecialVars[i].relatedObj[j]))
								{
									if (!CheckVar._SpecialVars[i].relatedExcel.Contains(tmpRelatedExcel))
									{
										CheckVar._SpecialVars[i].relatedExcel.Add(tmpRelatedExcel);
									}
								}
							}

							//判断运动的相对物体是否被随机变量，输入变量影响
							if (referenceObj != "" && CheckVar._SpecialVars[i].relatedObj.Contains(referenceObj))
							{
								//在随机变量中添加影响行
								if (!CheckVar._SpecialVars[i].relatedExcel.Contains(tmpRelatedExcel))
								{
									CheckVar._SpecialVars[i].relatedExcel.Add(tmpRelatedExcel);
								}

								//在随机变量中添加影响物体
								for (int j = 0; j < groupObjs.Count; j++)
								{
									if (!CheckVar._SpecialVars[i].relatedObj.Contains(groupObjs[j]))
									{
										CheckVar._SpecialVars[i].relatedObj.Add(groupObjs[j]);
									}
								}
							}
						}
					}
				}
				
			}

			//string tmpExcel = Motion.MotionPlatform.MotionPlatformData.excelName;
			//int tmpRow = (Motion.MotionPlatform.MotionPlatformData.mainRowNumber + 2);
			for (int i = 1; i < data_row_Content.Count; i++)
			{
				try
				{

					if (data_row[i].ToString() != "")
					{
						string[] tmpStr2 = data_row[i].ToString().Split(',');
						for (int j = 0; j < tmpStr2.Length; j++ )
						{
							if (tmpStr2[j][0] == '$')
							{
								string tmpStrssss = tmpStr2[j];
								tmpStr2[j] = VariableManager.GetExcelVarValue(tmpStr2[j], data_row_Content, motion_symbol, group_table);

								Debug.Log(tmpStrssss + "转换成" + tmpStr2[j]);
							}
						}

						data_row[i] = tmpStr2[0];
						if (tmpStr2.Length > 1)
						{
							for (int j = 1; j < tmpStr2.Length; j++)
							{
								data_row[i] += ("," + tmpStr2[j]);
							}
						}
						//data_row[i] = VariableManager.GetExcelVarValue(data_row[i].ToString());
					}
				}
				catch
				{
					break;
				}
			}
		}
	}

	/// <summary>
	/// 暂停子协程控制类，用于实现主流程中一些特殊的时间处理；
	/// </summary>
	public class Motion_SubWaitCoroutine
	{

		private static List<bool> _count = new List<bool>();

		/// <summary>
		/// 当前暂停子协程个数；
		/// </summary>
		public static int Count
		{
			get { return _count.Count; }
		}

		/// <summary>
		/// 加入一个暂停子协程；
		/// </summary>
		public static void AddOne()
		{
			_count.Add(true);
		}

		/// <summary>
		/// 移除一个暂停子协程；
		/// </summary>
		public static void RemoveOne()
		{
			if (_count.Count > 0)
				_count.RemoveAt(_count.Count - 1);
		}

		/// <summary>
		/// 清空所有暂停子协程；
		/// </summary>
		public static void Clear()
		{
			_count.Clear();
		}
	}

	/// <summary>
	/// 反射过程中，加载其他程序集中的Type；
	/// </summary>
	public class Motion_TypeGet
	{ 
		/// <summary>
		/// 加载其他程序集中的类型；
		/// </summary>
		/// <param name="type_string">对应的类型字符串；</param>
		/// <returns>返回该类型；</returns>
		public static Type MotionTypeGet(string type_string)
		{
			Type _t = Type.GetType(type_string);
			if (_t == null)
			{
				//反射当前程序集的信息
				Assembly csharpAssembly = Assembly.Load("Assembly-CSharp");
				_t = csharpAssembly.GetType(type_string);
				//假设程序集加载还不成功，遍历所有程序集
				if (_t == null)
				{
					foreach (Assembly assem in AppDomain.CurrentDomain.GetAssemblies())
					{
						//反射当前程序集的信息
						_t = assem.GetType(type_string);
						if (_t != null)
						{
							Debug.Log(assem.ToString() + " --- " + type_string + "，在其他程序集中加载到该类型！");
							break;
						}
					}
				}
			}
			if (_t == null)
			{
				Debug.LogError("Type: " + type_string + "，该类型在所有程序集中都不存在！");
			}
			return _t;
		}
	}

	/// <summary>
	/// Editor加密模块；
	/// </summary>
	public class Motion_EditorEncryption
	{
		public static bool IsAllowEditor
		{
			get { return _isAllowEditor; }
		}
		private static bool _isAllowEditor = false;


		public static void Deblocking(bool need_deblocking)
		{
			if (need_deblocking)
			{
				if (File.Exists(Application.dataPath + "/Editor_Key.txt"))
				{
					string SystemInfoMsg = "";
					try
					{
						SystemInfoMsg = SystemInfo.deviceModel + SystemInfo.deviceName + SystemInfo.deviceType + SystemInfo.graphicsDeviceID + SystemInfo.graphicsDeviceName + SystemInfo.operatingSystem + SystemInfo.processorCount + SystemInfo.systemMemorySize + SystemInfo.deviceModel;
					}
					catch
					{
						try
						{
							SystemInfoMsg = SystemInfo.deviceModel + SystemInfo.deviceName + SystemInfo.deviceType + SystemInfo.graphicsDeviceID + SystemInfo.graphicsDeviceName + SystemInfo.operatingSystem + SystemInfo.processorCount + SystemInfo.systemMemorySize + SystemInfo.deviceModel;
						}
						catch
						{
							Debug.LogError("解密出现一个小问题，请重新运行一下Unity工程（不需要关闭工程）！");
							return;
						}
					}
					//第一个盐值字符串
					string saltStr1 = "Sunnytech_JiangXiaolong_Editor_Salt";
					//MD5哈希生成类，生成哈希值
					MD5 md5Hash = MD5.Create();
					string md5Str = GetMd5Hash(md5Hash, SystemInfoMsg + saltStr1);
					//第二个盐值字符串，解密的过程其实是再加一次盐值
					string saltStr2 = "Sunnytech_JiangXiaolong_Editor_Deblocking_Salt";
					string md5StrFinal = GetMd5Hash(md5Hash, md5Str + saltStr2);
					//读取TXT文件
					FileStream fileStream = new FileStream(Application.dataPath + "/Editor_Key.txt", FileMode.Open, FileAccess.Read);
					StreamReader fileReader = new StreamReader(fileStream);
					string originalMd5 = fileReader.ReadLine().Trim();
					fileReader.Close();

					// Create a StringComparer an compare the hashes.
					StringComparer comparer = StringComparer.OrdinalIgnoreCase;
					if (0 == comparer.Compare(md5StrFinal, originalMd5))
					{
						_isAllowEditor = true;
					}
					else
					{
						_isAllowEditor = false;
					}
				}
				else
				{
					_isAllowEditor = false;
					Debug.LogWarning(Application.dataPath + "/Editor_Key.txt，该解密文件不存在！");
				}
			}
		}

		private static string GetMd5Hash(MD5 md5Hash, string input)
		{
			// Convert the input string to a byte array and compute the hash.
			byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

			// Create a new Stringbuilder to collect the bytes
			// and create a string.
			StringBuilder sBuilder = new StringBuilder();

			// Loop through each byte of the hashed data 
			// and format each one as a hexadecimal string.
			for (int i = 0; i < data.Length; i++)
			{
				sBuilder.Append(data[i].ToString("x2"));
			}

			// Return the hexadecimal string.
			return sBuilder.ToString();
		}


		// Verify a hash against a string.
		private static bool VerifyMd5Hash(MD5 md5Hash, string input, string hash)
		{
			// Hash the input.
			string hashOfInput = GetMd5Hash(md5Hash, input);

			// Create a StringComparer an compare the hashes.
			StringComparer comparer = StringComparer.OrdinalIgnoreCase;

			if (0 == comparer.Compare(hashOfInput, hash))
			{
				return true;
			}
			else
			{
				return false;
			}
		}
	}
}

